/**
 * axios请求封装
 */
import store from '../store'
import axios from 'axios'
import router from '@/router/routers'
import settings from '../settings'
import { getToken } from '@/utils/auth'
import qs from 'qs'
import { MessageBox, Notification, Loading } from 'element-ui'

// 基础参数配置
let base = {
	cType: 1, //1 'application/json' 2 'application/x-www-form-urlencoded' 默认1
	successCode: 0, //请求成功的code 默认0
	succeedMsg: null, // 请求成功后code为successCode的提示 为true的时候就用后端返回的文字 默认null
	erroredMsg: true, // 请求成功后code不是successCode的提示 为true的时候就用后端返回的文字 默认true
	loginLoseCode: 401, // 登录失效的code 默认401
	loading: {
		instance: null, // 加载实例 默认无
		type: 1, // 0不显示加载 1全局加载 2局部加载  默认1
		options: {
			target: 'document.body'
		}
	}
};
// let loadingInstance = Loading.service();
// 创建axios实例
const service = axios.create({
	baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '/api', // api 的 base_url
	timeout: settings.timeout, // 请求超时时间
})
// http请求拦截
service.interceptors.request.use(config => {
	base.succeedMsg = config.succeedMsg ? config.succeedMsg : null;
	base.erroredMsg = config.erroredMsg ? config.erroredMsg : true;
	base.cType = config.cType ? config.cType : 1;
	base.successCode = config.successCode ? config.successCode : 0;
	base.loginLoseCode = config.loginLoseCode ? config.loginLoseCode : 0;
	base.loading.type = config.loadingType ? config.loadingType : 0;
	base.loading.options.target = config.loadingTarget ? config.loadingTarget : 'document.body';
	if (base.loading.type != 0) base.loading.instance = Loading.service(base.loading.options);
	if (config.method == 'GET' || config.method == 'get') {
		if (!/\?/.test(config.url)) {
			let str = splitJoint(config.data);
			config.url += str;
		}
	}
	if (getToken()) {
		config.headers['token'] = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
	}
	switch (base.cType) {
		case 1:
			config.headers['Content-Type'] = 'application/json';
			break;
		case 2:
			config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
			config.data = qs.stringify(config.data); // 序列化，否则后端可能接受不到传的参数
			break;
		default:
			config.headers['Content-Type'] = 'application/json';
			break;
	}
	return config
}, error => {
	// Do something with request error
	console.log(error) // for debug
	Promise.reject(error)
});

function splitJoint(obj) {
	let arr = [];
	for (let key in obj) {
		arr.push(key + '=' + obj[key]);
	}
	return arr.length > 0 ? '?' + arr.join('&') : '';
}
// response 拦截器
service.interceptors.response.use(response => {
	if (base.loading.instance) base.loading.instance.close();
	const code = response.status
	if (code < 200 || code > 300) {
		Notification({
			title: '失败',
			message: '接口请求失败',
			type: 'error'
		})
		return Promise.reject('error')
	} else {
		if (base.successCode == response.data.code && base.succeedMsg) {
			Notification({
				title: '成功',
				message: base.succeedMsg == true ? response.data.msg : base.succeedMsg,
				type: 'success'
			})
			return response.data;
		} else if (base.successCode != response.data.code && base.erroredMsg) {
			Notification({
				title: '失败',
				message: base.erroredMsg == true ? response.data.msg : base.erroredMsg,
				type: 'error'
			})
			return Promise.reject(response.data);
		}
		return response.data;
	}
}, error => {
	if (base.loading.instance) base.loading.instance.close();
	let code = 0;
	try {
		code = error.response.data.status
	} catch (e) {
		if (error.toString().indexOf('Error: timeout') !== -1) {
			Notification({
				title: '失败',
				message: '网络请求超时',
				type: 'error'
			})
			return Promise.reject(error)
		}
	}
	if (code) {
		if (code === base.loginLoseCode) {
			MessageBox.confirm('登录状态已过期，您可以继续留在该页面，或者重新登录', '系统提示', {
				confirmButtonText: '重新登录',
				cancelButtonText: '取消',
				type: 'warning'
			}).then(() => {
				store.dispatch('LogOut').then(() => {
					location.reload() // 为了重新实例化vue-router对象 避免bug
				})
			})
		} else if (code === 403) {
			router.push({ path: '/401' })
		} else {
			const errorMsg = error.response.data.message
			if (errorMsg !== undefined) {
				Notification({
					title: '失败',
					message: errorMsg,
					type: 'error'
				})
			}
		}
	} else {
		Notification({
			title: '失败',
			message: '接口请求失败',
			type: 'error'
		})
	}
	return Promise.reject(error)
})
export default service;
